﻿namespace GoodAdmin.System;


/// <inheritdoc cref="IConfigService"/>
public class ConfigService : DbRepository<SysConfig>, IConfigService, ITransient
{
    private readonly IRedisCacheManager _redisService;

    public ConfigService(IRedisCacheManager redisService)
    {
        _redisService = redisService;
    }
    /// <inheritdoc/>
    public async Task AddConfig(ConfigAddInput input)
    {
        if(await IsAnyAsync(u => u.ConfigKey == input.ConfigKey))
        {
            throw Oops.Bah(ConfigErrorCode.C001);
        }
        var config= input.Adapt<SysConfig>();
        if(await InsertAsync(config))
            RefreshCache(input.Category);
    }

    /// <inheritdoc/>
    public async Task DeleteConfig(BaseIdInput input)
    {
        var config= await GetByIdAsync(input.Id);
        //系统内置配置不允许删除
        if(config.Category== CategoryConst.SYS_CONFIG)
        {
            throw Oops.Bah(ConfigErrorCode.C002);
        }
        if(await DeleteAsync(config))
            RefreshCache(config.Category);
    }

    /// <inheritdoc/>
    public async Task<ConfigOutput> GetSystemConfig()
    {
        var configList = await GetConfigListByCategory(CategoryConst.SYS_CONFIG);
        var array=new Dictionary<string, string>();
       configList.ForEach(config =>
        {
            array.Add(config.ConfigKey, config.ConfigValue);
        });
        return array.ToObject<ConfigOutput>();
    }

    /// <inheritdoc/>
    public async Task<SimpleConfig> GetConfigInfo(string Category, string configKey)
    {
        var configList = await GetConfigListByCategory(Category);
        var config = configList.FirstOrDefault(c=>c.ConfigKey==configKey);
        return config;
    }

    /// <inheritdoc/>
    public async Task<List<SimpleConfig>> GetConfigListByCategory(string Category)
    {
        var key = CacheConst.SysConfig + Category;
        var configList= _redisService.Get<List<SimpleConfig>>(key);
        if (configList == null)
        {
            configList= await DbContext.Db.Queryable<SysConfig>().Where(c => c.Category == Category).Select<SimpleConfig>().ToListAsync();           
            if(configList.Count>0)
                _redisService.Set(key, configList);
        }
        return configList;
    }

    /// <inheritdoc/>
    public async Task<SqlSugarPagedList<SysConfig>> GetConfigPageList(ConfigPageInput input)
    {
        return await Context.Queryable<SysConfig>()
            .WhereIF(!string.IsNullOrEmpty(input.Category), c => c.Category == input.Category)
            .OrderBy(c=>c.OrderField)
            .ToPagedListAsync(input.PageIndex, input.PageSize);
    }

    /// <inheritdoc/>
    public async Task UpdateConfig(ConfigUpdateInput input)
    {
        var configList = await GetConfigListByCategory(input.Category);
        var config = configList.Where(c => c.Id == input.Id).FirstOrDefault();
        //不能修改系统内置配置key及分类
        if (config.Category==CategoryConst.SYS_CONFIG )
        {
            if(config.Category != input.Category)
                throw Oops.Bah(ConfigErrorCode.C003);
            if(config.ConfigKey != input.ConfigKey)
                throw Oops.Bah(ConfigErrorCode.C004);
        }
        //检查是否存在相同key
        else
        {            
            if (configList.Where(c => c.ConfigKey == input.ConfigKey).Any())
            {
                throw Oops.Bah(ConfigErrorCode.C001);
            }
        }
        var configEntity = input.Adapt<SysConfig>();

        if(await UpdateAsync(configEntity))
             RefreshCache(input.Category);
    }

    /// <inheritdoc/>
    public async Task UpdateSystemConfig(SystemConfigUpdateInput input)
    {
        var configList = await GetConfigListByCategory(CategoryConst.SYS_CONFIG);
        var newList= new List<SysConfig>();
        var dic = input.ToObject<Dictionary<string,string>>();
        configList.ForEach(item =>
        {
            var nowValue = dic[item.ConfigKey];
            //数据做了更改的才更新
            if (item.ConfigValue != nowValue)
            {
                item.ConfigValue = dic[item.ConfigKey];
                newList.Add(item.Adapt<SysConfig>());
            }            
        });
        if(await UpdateRangeAsync(newList))
            RefreshCache(CategoryConst.SYS_CONFIG);
    }

    /// <summary>
    /// 刷新缓存
    /// </summary>
    public void RefreshCache(string category)
    {
        var key = CacheConst.SysConfig + category;
        //先移除该分类缓存
        _redisService.Remove(key);
    }
}